/*
  TFFS - Tin Foil File System.
         Tomorrow's Fast File System (because it's slow today)
	 Trust in Failures File System
*/

#include <stdio.h>
#include <stdlib.h>

#include <fuse/fuse.h>

#include "fuse_entrypoints.h"
#include "glog/logging.h"

void populate_fuse_operations(struct fuse_operations* operations) {
    operations->getattr = tffs_getattr;
    operations->readlink = tffs_readlink;
    operations->mknod = tffs_mknod;
    operations->mkdir = tffs_mkdir;
    operations->unlink = tffs_unlink;
    operations->rmdir = tffs_rmdir;
    operations->symlink = tffs_symlink;
    operations->chmod = tffs_chmod;
    operations->chown = tffs_chown;
    operations->truncate = tffs_truncate;
    operations->rename = tffs_rename;
    operations->link = tffs_link;
    operations->utimens = tffs_utimens;
    operations->open = tffs_open;
    operations->read = tffs_read;
    operations->write = tffs_write;
    operations->statfs = tffs_statvfs;
    //operations->flush = tffs_flush;
    operations->release = tffs_release;
    //operations->fsync = tffs_fsync;
    operations->opendir = tffs_opendir;
    operations->readdir = tffs_readdir;
    operations->releasedir = tffs_releasedir;
    //operations->fsyncdir = tffs_fsyncdir;
    operations->access = tffs_access;
    operations->create = tffs_create;
    operations->ftruncate = tffs_ftruncate;
    operations->fgetattr = tffs_fgetattr;
}

int main(int argc, char *argv[]) {
    google::InitGoogleLogging(argv[0]);

    if (argc < 2) {
        LOG(ERROR) << "Usage " << argv[0] << " <real_path> [other fuse options]";
        return 1;
    }

    char** morphed_argv = (char**)alloca(argc * sizeof(char**));
    morphed_argv[0] = argv[0];
    set_target_dir(argv[1]);
    set_mount_point(argv[2]);
    
    LOG(INFO) << "Final target dir is:" << get_target_dir();

    for (int i = 2; i < argc; ++i) {
        morphed_argv[i-1] = argv[i];
    }
    morphed_argv[argc-1] = NULL;
    

    // TODO(awong): We should that the file system actually has user_xattr
    // enabled, and bail if not.

    struct fuse_operations tffs_oper = {};
    populate_fuse_operations(&tffs_oper);
    return fuse_main(argc - 1, morphed_argv, &tffs_oper, NULL);
}

